// import G6 from '@antv/g6/build/g6'
import G6 from '../../../../../../public/g6/index'
import { uniqueId } from '../../utils'
const MIN_ARROW_SIZE = 3

const customEdge = {
  init() {
    const dashArray = [
      [0, 1],
      [0, 2],
      [1, 2],
      [0, 1, 1, 2],
      [0, 2, 1, 2],
      [1, 2, 1, 2],
      [2, 2, 1, 2],
      [3, 2, 1, 2],
      [4, 2, 1, 2]
    ]

    const lineDash = [4, 2, 1, 2]
    const interval = 9
    G6.registerEdge('customArcWithArrow', {
      draw(cfg, group) {
        const { source, target, points } = cfg

        let sourceNode, targetNode, start, end
        if (typeof cfg.source === 'string') {
          cfg.source = cfg.sourceNode
        }
        if (!cfg.start) {
          cfg.start = {
            x: 0,
            y: 0
          }
        }
        if (!cfg.end) {
          cfg.end = {
            x: 0,
            y: 0
          }
        }
        if (!cfg.source.x) {
          sourceNode = cfg.source.getModel()
          start = {
            x: sourceNode.x + cfg.start.x,
            y: sourceNode.y + cfg.start.y
          }
        } else {
          start = cfg.source
        }
        if (typeof cfg.target === 'string') {
          cfg.target = cfg.targetNode
        }
        if (!cfg.target.x) {
          targetNode = cfg.target.getModel()
          end = { x: targetNode.x + cfg.end.x, y: targetNode.y + cfg.end.y }
        } else {
          end = cfg.target
        }

        sourceNode = cfg.sourceNode.getModel()
        targetNode = cfg.targetNode.getModel()

        const sourcePos = cfg.source._cfg.bboxCache.centerX
        const targetPos = cfg.target._cfg.bboxCache.centerX
        const sourceRadius = sourceNode.size / 2
        const targetRadius = targetNode.size / 2

        const arrowEndPos = this.getArrowPositionOnCircle(
          targetPos,
          targetRadius,
          end
        )

        // 获取源节点和目标节点的位置和大小
        const sourceBBox = {
          centerX: sourceNode.x + cfg.start.x,
          centerY: sourceNode.y + cfg.start.y,
          width: 80
        }
        const targetBBox = {
          centerX: targetNode.x + cfg.end.x,
          centerY: targetNode.y + cfg.end.y,
          width: 80
        }
        const sourceCenter = { x: sourceBBox.centerX, y: sourceBBox.centerY }
        const targetCenter = { x: targetBBox.centerX, y: targetBBox.centerY }
        // const sourceRadius = sourceBBox.width / 2 // 假设节点是正方形或圆形，且宽度和高度相等
        // const targetRadius = targetBBox.width / 2

        // 计算边的中点（这里以源节点为例，实际上你可能需要根据边的路由来计算）
        // 注意：这个中点计算是简化的，仅用于说明如何开始。
        // 在实际应用中，你可能需要根据边的具体路由（如是否经过圆心、弯曲程度等）来计算。
        const midPoint = {
          x: (sourceCenter.x + targetCenter.x) / 2,
          y: (sourceCenter.y + targetCenter.y) / 2
        }

        // 计算箭头应放置的圆上点的坐标
        // 这里我们假设箭头指向从源节点到目标节点的方向上的圆上一点
        // 你需要根据实际情况调整这个计算逻辑
        const arrowAngle = Math.atan2(
          targetCenter.y - sourceCenter.y,
          targetCenter.x - sourceCenter.x
        )
        const arrowOffsetX = sourceRadius + 10 // 偏移量，确保箭头不被圆形节点遮挡
        const arrowPosition = {
          x: sourceCenter.x + arrowOffsetX * Math.cos(arrowAngle),
          y: sourceCenter.y - arrowOffsetX * Math.sin(arrowAngle) // 注意Y坐标的符号
        }

        let path = []
        let hgap = Math.abs(targetBBox.centerX - sourceBBox.centerX)
        if (targetBBox.centerX > sourceBBox.centerX) {
          path = [
            ['M', sourceBBox.centerX, sourceBBox.centerY],
            [
              'C',
              sourceBBox.centerX,
              sourceBBox.centerY + hgap / (hgap / 50),
              targetBBox.centerX,
              targetBBox.centerY - hgap / (hgap / 50),
              targetBBox.centerX,
              targetBBox.centerY - 4
            ],
            ['L', targetBBox.centerX, targetBBox.centerY]
          ]
        } else {
          path = [
            ['M', sourceBBox.centerX, sourceBBox.centerY],
            [
              'C',
              sourceBBox.centerX,
              sourceBBox.centerY + hgap / (hgap / 50),
              targetBBox.centerX,
              targetBBox.centerY - hgap / (hgap / 50),
              targetBBox.centerX,
              targetBBox.centerY - 4
            ],
            ['L', targetBBox.centerX, targetBBox.y]
          ]
        }
        const startPoint = cfg.startPoint
        const endPoint = cfg.endPoint
        // 绘制箭头
        group.addShape('path', {
          attrs: {
            path: [
              // 用path路径配置带折点的连接线 M表示开始的坐标，L表示拐点的坐标
              ['M', startPoint.x, startPoint.y],
              ['L', (startPoint.x + endPoint.x) / 2, startPoint.y],
              ['L', (startPoint.x + endPoint.x) / 2, endPoint.y],
              ['L', endPoint.x, endPoint.y]
            ],
            stroke: 'yellow',
            lineAppendWidth: 10,
            endArrow: true, // 箭头形状和大小
            fill: 'red'
          },
          shape: 'arc',
          name: 'edge-arrow',
          x: arrowPosition.x,
          y: arrowPosition.y,
          rotate: this.getArrowRotateAngle(targetPos, arrowEndPos) // 将弧度转换为角度，并调整旋转方向
        })

        const midX =
          sourceBBox.centerX + (targetBBox.centerX - sourceBBox.centerX) / 2.5
        const midY =
          sourceBBox.centerY + (targetBBox.centerY - sourceBBox.centerY) / 2.5

        group.addShape('text', {
          attrs: {
            text: cfg.name,
            x: midX,
            y: midY,
            fill: 'yellow' // 连线颜色
          }
        })

        return null
      },
      getArcPath(cfg) {
        const startPoint = cfg.startPoint
        const endPoint = cfg.endPoint
        const controlPoints = cfg.controlPoints || [] // 你可以根据需要添加控制点

        // 假设只使用两个端点来生成弧
        const radius =
          Math.sqrt(
            Math.pow(endPoint.x - startPoint.x, 2) +
              Math.pow(endPoint.y - startPoint.y, 2)
          ) / 2
        const centerX = (startPoint.x + endPoint.x) / 2
        const centerY = (startPoint.y + endPoint.y) / 2

        // 使用 canvas API 的 `arc` 方法生成路径字符串
        const startAngle = Math.atan2(
          startPoint.y - centerY,
          startPoint.x - centerX
        )
        const endAngle = Math.atan2(endPoint.y - centerY, endPoint.x - centerX)

        // 生成路径数据
        const path = [
          ['M', startPoint.x, startPoint.y], // 移动到起点
          ['A', radius, radius, 0, 0, 1, endPoint.x, endPoint.y] // 画弧到终点
        ]

        return G6.Util.getPathString(path)
      },
      getArrowPositionOnCircle(center, radius, endPoint) {
        const angle = Math.atan2(endPoint.y - center.y, endPoint.x - center.x)
        const offsetX = radius + 10 // 箭头的偏移量
        return {
          x: center.x + offsetX * Math.cos(angle),
          y: center.y - offsetX * Math.sin(angle) // 注意Y坐标的符号，因为屏幕坐标系是y轴向下的
        }
      },

      // 辅助方法：计算箭头的旋转角度
      getArrowRotateAngle(center, arrowEndPos) {
        const angle = Math.atan2(
          arrowEndPos.y - center.y,
          arrowEndPos.x - center.x
        )
        return -angle * (180 / Math.PI) // 将弧度转换为角度，并调整旋转方向
      },
      afterDraw(cfg, group) {
        if (
          cfg.source.getModel().isDoingStart &&
          cfg.target.getModel().isDoingEnd
        ) {
          const shape = group.get('children')[0]
          const length = shape.getTotalLength() // G 增加了 totalLength 的接口
          let totalArray = []
          for (var i = 0; i < length; i += interval) {
            totalArray = totalArray.concat(lineDash)
          }
          let index = 0
          shape.animate(
            {
              onFrame() {
                const cfg = {
                  lineDash: dashArray[index].concat(totalArray)
                }
                index = (index + 1) % interval
                return cfg
              },
              repeat: true
            },
            3000
          )
        }
      },
      setState(name, value, item) {
        const group = item.getContainer()
        const shape = group.get('children')[0]
        const selectStyles = () => {
          shape.attr('stroke', '#6ab7ff')
        }
        const unSelectStyles = () => {
          shape.attr('stroke', '#b8c3ce')
        }

        switch (name) {
          case 'selected':
          case 'hover':
            if (value) {
              selectStyles()
            } else {
              unSelectStyles()
            }
            break
        }
      }
    })
    // G6.registerEdge('link-edge', {
    //   draw(cfg, group) {
    //     let sourceNode, targetNode, start, end
    //     if (!cfg.source.x) {
    //       sourceNode = cfg.source.getModel()
    //       start = {
    //         x: sourceNode.x + cfg.start.x,
    //         y: sourceNode.y + cfg.start.y
    //       }
    //     } else {
    //       start = cfg.source
    //     }
    //     if (!cfg.target.x) {
    //       targetNode = cfg.target.getModel()
    //       end = { x: targetNode.x + cfg.end.x, y: targetNode.y + cfg.end.y }
    //     } else {
    //       end = cfg.target
    //     }

    //     let path = []
    //     path = [
    //       ['M', start.x, start.y],
    //       ['L', end.x, end.y]
    //     ]
    //     const keyShape = group.addShape('path', {
    //       attrs: {
    //         id: 'edge' + uniqueId(),
    //         path: path,
    //         stroke: '#1890FF',
    //         strokeOpacity: 1,
    //         lineDash: [5, 5]
    //       }
    //     })
    //     return keyShape
    //   }
    // })
    G6.registerEdge('flow-line', {
      draw(cfg, group) {
        const startPoint = cfg.startPoint
        const endPoint = cfg.endPoint
        console.log(startPoint, endPoint, '@@')

        const { style } = cfg
        const shape = group.addShape('path', {
          attrs: {
            stroke: 'red',
            animate: true,
            endArrow: {
              path: '箭头，他的角度，'
            }, // 需要箭头可以自己配置箭头 有开始箭头和结束箭头
            path: [
              // 用path路径配置带折点的连接线 M表示开始的坐标，L表示拐点的坐标
              ['M', startPoint.x, startPoint.y],
              ['L', (startPoint.x + endPoint.x) / 2, startPoint.y],
              ['L', (startPoint.x + endPoint.x) / 2, endPoint.y],
              ['L', endPoint.x, endPoint.y]
            ]
          }
        })
        return shape
      },
      afterDraw(cfg, group) {
        const shape = group.get('children')[0]
        const startPoint = shape.getPoint(0)
        //创建节点之间的圆圈，并为每一个设置样式
        const circle = group.addShape('circle', {
          attrs: {
            x: startPoint.x + 92,
            y: startPoint.y,
            fill: '#cbdaff',
            r: 4 //圆圈大小
          },
          name: 'circle-shape'
        })
        // 实现动态效果，从线的开始滑到结束
        circle.animate(
          ratio => {
            const tmpPoint = shape.getPoint(ratio)
            return {
              x: tmpPoint.x,
              y: tmpPoint.y
            }
          },
          {
            repeat: 1, //动画是否重复
            duration: 3000 //一次动画持续时长
          }
        )
      }
    })
  }
}

export default customEdge
